package cn.hengzhu.main_manager.web.xcx;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import javax.servlet.http.HttpServletRequest;
import cn.hengzhu.main_manager.repository.domain.*;
import cn.hengzhu.main_manager.repository.vo.ManageCaseBoxVO;
import cn.hengzhu.main_manager.service.*;
import cn.hengzhu.main_manager.utils.*;
import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import com.alibaba.fastjson.JSONObject;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.request.AlipayTradeCreateRequest;
import com.alipay.api.response.AlipayTradeCreateResponse;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import cn.hengzhu.main_manager.repository.dao.CustomersAmountMapper;
import cn.hengzhu.main_manager.repository.dao.ManageCaseBoxMapper;
import cn.hengzhu.main_manager.repository.dao.ManageCaseMapper;
import cn.hengzhu.main_manager.repository.dao.ManageCaseTypeMapper;
import cn.hengzhu.main_manager.repository.dao.MobileBindKeyMapper;
import cn.hengzhu.main_manager.repository.dao.PayOrderMapper;
import cn.hengzhu.main_manager.repository.dao.PrepayOrderMapper;
import cn.hengzhu.main_manager.repository.dao.SysConstMapper;
import cn.hengzhu.main_manager.repository.vo.UsingBoxByXcxVO;
import cn.hengzhu.main_manager.repository.vo.XcxUseBoxVO;
import cn.hengzhu.main_manager.utils.config.AllConst;
import cn.hengzhu.main_manager.utils.config.AppConfig;
import cn.hengzhu.main_manager.utils.config.xcx.AliConfig;
import static cn.hengzhu.main_manager.utils.ReturnMapUtils.*;


/**
 *
 * @author 刘成
 * @since 2018年10月12日 支付宝小程序常规柜子项目
 */
@Controller
@RequestMapping("/alixcxCommon")
public class ALiXcxCommonContrller {
	private static Logger log = Logger.getLogger(ALiXcxCommonContrller.class);
	@Autowired
	private ManageCaseMapper manageCaseMapper;
	@Autowired
	private ManageCaseTypeMapper manageCaseTypeMapper;
	@Autowired
	private ManageCaseBoxMapper manageCaseBoxMapper;
	@Autowired
	private CustomersAmountMapper customersAmountMapper;
	@Autowired
	private ManageCaseBoxService manageCaseBoxService;
	@Autowired
	private PayOrderMapper payOrderMapper;
	@Autowired
	private PayOrderService payOrderService;
	@Autowired
	private PrepayOrderMapper prepayOrderMapper;
	@Autowired
	private SysConstMapper sysConstMapper;
	@Autowired
	private CustomersAmountService customersAmountService;
	@Autowired
	MobileBindKeyMapper mobileBindKeyMapper;
	@Autowired
	MobileBindKeyService mobileBindKeyService;
	@Autowired
	ManageCaseTypeService manageCaseTypeService;
	@Autowired
	ManageCaseTypePriceService manageCaseTypePriceService;


	/**
	 * 发送验证码
	 * 
	 * @author 周磊
	 * @since 2019年6月28日
	 * @param phone
	 * @return
	 * @throws Exception
	 */
	@RequestMapping("/sendMsgCode")
	@ResponseBody
	public Map<String, Object> sendMsg(String phone) throws Exception {
		Map<String, Object> map = new HashMap<String, Object>();
		if (!AliMsmUtils.isMobile(phone)) {
			map.put("jump", "0");
			map.put("pagejump", "500");
			map.put("hzmessageyy", "手机号格式不正确!!!");
			return map;
		}
		String code = AliMsmUtils.getCode(); // 生产一个随机的验证码
		if (mobileBindKeyService.sendMessage(code, phone)) {
			map.put("jump", "0");
			map.put("pagejump", "200");
			map.put("hzmessageyy", "验证码发送成功!!!");
			return map;
		}
		map.put("jump", "0");
		map.put("pagejump", "500");
		map.put("hzmessageyy", "验证码发送失败!!!");
		return map;
	}

	/**
	 * 绑定手机号
	 * 
	 * @author 周磊
	 * @since 2019年6月28日
	 * @param openId
	 * @param phone
	 * @param code
	 * @return
	 * @throws Exception
	 */
	@RequestMapping("/bindPhone")
	@ResponseBody
	public Map<String, Object> bindPhone(String openId, String phone, String code) throws Exception {
		Map<String, Object> map = new HashMap<String, Object>();
		if (!AliMsmUtils.isMobile(phone)) {
			map.put("jump", "0");
			map.put("pagejump", "500");
			map.put("hzmessageyy", "手机号格式不正确!!!");
			return map;
		}
		if (code == null || "".equals(code)) {
			map.put("jump", "0");
			map.put("pagejump", "500");
			map.put("hzmessageyy", "验证码不正确!!!");
			return map;
		}
		if (openId == null || "".equals(openId)) {
			map.put("jump", "0");
			map.put("pagejump", "500");
			map.put("hzmessageyy", "获取登陆失败,请重试");
			return map;
		}
		if (mobileBindKeyService.verifyCode(code, phone, openId)) {
			map.put("jump", "0");
			map.put("pagejump", "200");
			map.put("hzmessageyy", "绑定成功");
			return map;
		}
		map.put("jump", "0");
		map.put("pagejump", "500");
		map.put("hzmessageyy", "验证码无效");
		return map;
	}

	/**
	 * 是否绑定手机
	 * 
	 * @author 周磊
	 * @since 2019年6月28日
	 * @param openId
	 * @return
	 */
	@RequestMapping("/isBindPhone")
	@ResponseBody
	public Map<String, Object> isBindPhone(String openId) {
		Map<String, Object> map = new HashMap<String, Object>();
		if (openId == null || "".equals(openId)) {
			map.put("pagejump", "500");
			map.put("hzmessageyy", "获取登陆失败,请重试");
			return map;
		}
		MobileBindKeyExample example = new MobileBindKeyExample();
		example.createCriteria().andOpenIdEqualTo(openId);
		List<MobileBindKey> mbkms = mobileBindKeyMapper.selectByExample(example);
		if (mbkms.isEmpty()) {
			map.put("pagejump", "600");
			map.put("hzmessageyy", "未绑定手机");
			return map;
		}
		map.put("pagejump", "200");
		map.put("hzmessageyy", "已绑定手机");
		return map;
	}


	/**
	 * @author 谭芸
	 * @since 2021年3月30号
	 * 共享玩具车柜子扫码功能
	 * @param caseNo mac地址
	 * @param openId 微信用户唯一标识
	 * @param timestamp
	 * @return
	 */
	@RequestMapping("/getBaseInfo")
	@ResponseBody
	public Map<String,Object> getBaseInfo(String caseNo, String openId, Long timestamp) {
		caseNo = caseNo.substring(3);
		Map<String, Object> map = new HashMap<String, Object>();
		//判断二维码是否过期
		if (timestamp != null && (timestamp + (1000L * 60L * 2L)) < System.currentTimeMillis()) {
			genarateMap(map, "该二维码已过期!!!");
			return map;
		}
		// 是否有用户唯一标识
		if (StringUtils.isEmpty(openId)) {
			genarateMap(map, "获取用户信息失败，请重新扫描二维码!!!");
			return map;
		}

		// 柜子是否在线
		ManageCaseExample manageCaseExample = new ManageCaseExample();
		manageCaseExample.createCriteria().andCaseNoEqualTo(caseNo); // CASE_NO =
		List<ManageCase> manageCaseList = manageCaseMapper.selectByExample(manageCaseExample);
		ManageCase manageCase = manageCaseList.get(0);

		Integer typeId = manageCase.getTypeId();
		Byte isOnline = manageCase.getIsOnline();
		Byte isNormal = manageCase.getIsNormal();

		if (Byte.valueOf("1").equals(isOnline) && Byte.valueOf("1").equals(isNormal)  ){
			// 柜子正常且在线
			// 是否需要绑定手机
			ManageCaseType manageCaseType = manageCaseTypeMapper.selectByPrimaryKey(typeId);
			Byte isBindMobile = manageCaseType.getIsBindMobile();
			if (isBindMobile == 1 && "600".equals(isBindPhone(openId).get("pagejump"))){ // 是否强制绑定手机 且 还没有绑定手机
				map.put("isBandMobile", 1);
				return map;
			}

			// 1.判断用户是否欠费
			CustomersAmount owe = customersAmountService.isOwe(openId);
			BigDecimal totalAmount = owe.getTotalAmount();

			if (totalAmount.compareTo(BigDecimal.ZERO) == -1){
				// 欠费。小程序调用充值界面
				map.put("pagejump", "300");
				map.put("hzmessageyy", "充值");

//				try {
//					WXxcxController wXxcxController = new WXxcxController();
//					Map recharge = wXxcxController.recharge(openId, totalAmount.toString());
//					return (Map<String, Object>) recharge;
//				} catch (Exception e) {
//					genarateMap(map,"充值失败，请稍后重试");
//					return map;
//				}
			}

			// 2.判断是否在此柜租车
			ManageCaseBoxExample caseBoxxample = new ManageCaseBoxExample();
			//from  manage_case_box where CASE_NO = caseNo and USER_ID = openId and IS_DEL = 0 and USE_STATUS =1
			caseBoxxample.createCriteria().andCaseNoEqualTo(caseNo).andUserIdEqualTo(openId)
					.andIsDelEqualTo((byte) 0).andUseStatusEqualTo((byte) 1);
			List<ManageCaseBox> mcbList = manageCaseBoxMapper.selectByExample(caseBoxxample);
			if (!mcbList.isEmpty()) { // 在此租车, 选择续时或者结束使用
				Integer id = mcbList.get(0).getId();
				map.put("pagejump","302");
				map.put("boxId",id);
				return map;
			}

			// 没有在此租车
			map.put("pagejump", "301");
			map.put("typeId",typeId);
			map.put("caseNo",caseNo);
			return map;

		}else if (Byte.valueOf("0").equals(isOnline)){
			// 柜子不在线
			genarateMap(map,"该储物柜未连接网络，暂不能操作，请联系门店管理员处理!");
		}else{
			// 柜子不正常
			genarateMap(map, "设备异常，请联系管理员!");
		}

		return map;

	}

	/**
	 * 获取柜子对应的收费规则列表
	 * @param typeId
	 * @return
	 */
	@ResponseBody
	@RequestMapping("/payType")
	public List<ManageCaseTypePrice> payType(Integer typeId) throws Exception {
		List<ManageCaseTypePrice> chargeTypes = manageCaseTypePriceService.getChargeType(typeId);
		return chargeTypes;
	}


	/**
	 * TODO 此接口不使用
	 * @author 刘成
	 * @since 2018年10月15日
	 * @param caseNo 柜子mac地址
	 * @param openId 微信登录用户唯一标识
	 * @param timestamp
	 * @return
	 * @throws Exception
	 * @判断是存物还是取物拿到柜子的基本信息 jump： 200---存物(不区分大小柜) 300 ---存物（区分大小柜） 501---获取用户信息失败
	 *                     100---取物
	 */
	@RequestMapping("/getBaseInfo1")
	@ResponseBody
	public Map<String, Object> getBaseInfo1(String caseNo, String openId, Long timestamp) throws Exception {

		caseNo = caseNo.substring(3);
		Map<String, Object> map = new HashMap<String, Object>();

		if (timestamp != null && (timestamp + (1000L * 60L * 2L)) < System.currentTimeMillis()) {
			map.put("jump", "0");
			map.put("pagejump", "500");
			map.put("hzmessageyy", "该二维码已过期!!!");
			return map;
		}
		if (StringUtils.isEmpty(openId)) {
			map.put("jump", "0");
			map.put("pagejump", "500");
			map.put("hzmessageyy", "获取用户信息失败，请重新扫描二维码!!!");
		} else {
			// 查询储物柜状态
			ManageCaseExample manageCaseExample = new ManageCaseExample();
			manageCaseExample.createCriteria().andCaseNoEqualTo(caseNo); //from manage_case where CASE_NO =      扫码的柜子mac地址来查询
			List<ManageCase> manageCaseList = manageCaseMapper.selectByExample(manageCaseExample);
			ManageCase manageCase = manageCaseList.get(0); // 查询出当前mac地址的柜子状态

			Byte isOnline = manageCase.getIsOnline();  //是否在线
			Byte isNormal = manageCase.getIsNormal();  //是否正常

			if (Byte.valueOf("1").equals(isOnline)) {
				if (Byte.valueOf("1").equals(isNormal)) {
					// 查询此用户是否使用了当前了柜子下的箱子
					ManageCaseBoxExample caseBoxxample = new ManageCaseBoxExample();
                    //from  manage_case_box  where  CASE_NO = caseNo and USER_ID = openId and IS_DEL = 0 and USE_STATUS =1
					caseBoxxample.createCriteria().andCaseNoEqualTo(caseNo).andUserIdEqualTo(openId)
							.andIsDelEqualTo((byte) 0).andUseStatusEqualTo((byte) 1);
					List<ManageCaseBox> selectByExample2 = manageCaseBoxMapper.selectByExample(caseBoxxample);

					// 查到到了就是使用了
					if (!selectByExample2.isEmpty()) {// 取物
						// 查询储物柜收费信息
						Integer typeId = manageCase.getTypeId();
						if (null != typeId) {
							ManageCaseType manageCaseType = manageCaseTypeMapper.selectByPrimaryKey(typeId);// 查询出对于对应收费类型的信息
							Byte payType = manageCaseType.getPayType(); // '收费类型（0，免费  1.计时   2.记次）'
							if (Byte.valueOf("0").equals(payType)) {  // 返回此就可以开门了
								map.put("pagejump", "101");
								map.put("jump", "1");
								map.put("caseNo", caseNo); // mac地址
								map.put("ishalfwayopen", selectByExample2.get(0).getIsHalfwayOpen());
								map.put("hzmessageyy", "您正在执行取物操作，请点击确定即可开启箱门！！!");
							} else {
								map.put("pagejump", "100");
								map.put("jump", "1");
								map.put("caseNo", caseNo); // mac地址
								map.put("ishalfwayopen", selectByExample2.get(0).getIsHalfwayOpen()); // 是否中途取过物
								map.put("isMidwayFetch",manageCaseType.getIsMidwayFetch()); // 是否可以中途取物(1.是   0.否）
								// CashPledge 收取押金
								map.put("isNeedCashPledge",manageCaseType.getCashPledge() != null
										&& manageCaseType.getCashPledge().compareTo(BigDecimal.ZERO) > 0 ? 1:0);
								map.put("hzmessageyy", "您正在执行取物操作，请点击确定，我们会为您生成账单，谢谢您的支持！！!");
							}
						} else {
							map.put("jump", "0");
							map.put("pagejump", "500");
							map.put("hzmessageyy", "系统错误，请联系管理员！！!");
						}

					} else {// 存物
						// 押金，目前使用于计时收费（如果为提前支付：押金+费用，使用完退押金；如果是用之后支付：则用之前需要支付押金，之后多押金里多退少补的方式进行），默认为0
						BigDecimal cashPledge = new BigDecimal("0.00");
						ManageCaseExample example = new ManageCaseExample();
						example.createCriteria().andCaseNoEqualTo(caseNo); // from manage_case CASE_NO = caseNo
						List<ManageCase> selectByExample = manageCaseMapper.selectByExample(example); // 查询出mac地址对应柜子信息

						if (!selectByExample.isEmpty()) {
							Integer typeId = manageCase.getTypeId(); // 获取收费类型的id
							if (typeId != null) {
								Byte isSize = manageCase.getIsSize(); // 是否区分大中小柜(1.是   0.否）
								ManageCaseType selectByPrimaryKey = manageCaseTypeMapper.selectByPrimaryKey(typeId); // 对应收费类型的信息

								if (selectByPrimaryKey != null) { // 对应收费类型不为空
									Byte isBandMobile = selectByPrimaryKey.getIsBindMobile();// 是否需要绑定手机 （0否 1是）
									if (selectByPrimaryKey.getCashPledge() != null) {
										cashPledge = selectByPrimaryKey.getCashPledge(); // 押金多少
									}
									Byte payType = selectByPrimaryKey.getPayType(); // 收费类型是什么 0.免费  1.计时   2.记次

									if (Byte.valueOf("0").equals(isSize)) { //不区分中小柜
										String price = selectByPrimaryKey.getPrice(); // 收费金额
										Byte payTime = selectByPrimaryKey.getPayTime(); // 收费时间（1.使用后收费  2.使用前收费）

										if (Byte.valueOf("0").equals(payType)) {// 免费
											map.put("pagejump", "200");
											map.put("jump", "2");
											map.put("isBandMobile", isBandMobile);
											map.put("hzmessageyy", "免费");
											map.put("caseNo", caseNo);
											map.put("size", 0);
										} else if (Byte.valueOf("1").equals(payType)) { // 不区分大小柜收费形式为计时
											String userTime = selectByPrimaryKey.getUserTime(); // 计时时使用（计时收费的时间）单位小时

											if (Byte.valueOf("2").equals(payTime)) { // 使用前收费
												map.put("hzmessageyy", price + "元/" + userTime + "小时," + "使用前需预支付:"
														+ price + "元,押金:" + cashPledge + "元"); // cashPledge 押金
											} else { // 使用后收费
												map.put("hzmessageyy",
														price + "元/" + userTime + "小时,使用前需支付押金:" + cashPledge + "元");
											}
											map.put("pagejump", "200");
											map.put("jump", "2");
											map.put("isBandMobile", isBandMobile);
											map.put("caseNo", caseNo);
											map.put("size", 0);

										} else if (Byte.valueOf("2").equals(payType)) { // 不区分大小柜收费形式为记次
											if (Byte.valueOf("2").equals(payTime)) {  // 使用前收费
												map.put("hzmessageyy", price + "/次" + ",使用前需预支付:" + price + "元,押金:"
														+ cashPledge + "元");
											} else {
												map.put("hzmessageyy", price + "/次" + ",使用前需预支付押金:" + cashPledge + "元");
											}
											map.put("jump", "2");
											map.put("pagejump", "200");
											map.put("isBandMobile", isBandMobile);
											map.put("caseNo", caseNo);
											map.put("size", 0);
										}
									} else if (Byte.valueOf("1").equals(isSize)) {// 此柜区分大小柜
										String priceSize = selectByPrimaryKey.getPriceSize(); // 区分大中小柜的价格字段（大中小按逗号分隔）
										Byte payTime = selectByPrimaryKey.getPayTime(); // 收费时间（1.使用后收费  2.使用前收费）

										if (Byte.valueOf("0").equals(payType)) {// 区分大小柜且免费
											map.put("pagejump", "300");
											map.put("jump", "3");
											map.put("caseNo", caseNo);
											map.put("isBandMobile", isBandMobile);
											map.put("hzmessageyy", "免费");
											map.put("big", "免费");
											map.put("medium", "免费");
											map.put("small", "免费");
										} else if (Byte.valueOf("1").equals(payType)) {  //区分大小柜且收费形式为计时

											if (StringUtils.isNotBlank(priceSize)) { // 大中小柜价格字段不为空
												List<String> asList = Arrays.asList(priceSize.split(",")); // 切割大中小柜子的价格
												String userTime = selectByPrimaryKey.getUserTime(); // 计时时使用（计时收费的时间）单位小时

												if (Byte.valueOf("2").equals(payTime)) { //收费前收费
													map.put("big", asList.get(0) + "元/" + userTime + "小时," + "使用前需预支付"
															+ asList.get(0) + "元,押金:" + cashPledge + "元");
													map.put("medium", asList.get(1) + "元/" + userTime + "小时,"
															+ "使用前需预支付" + asList.get(1) + "元,押金:" + cashPledge + "元");
													map.put("small", asList.get(2) + "元/" + userTime + "小时," + "使用前需预支付"
															+ asList.get(2) + "元,押金:" + cashPledge + "元");
												} else { //使用后收费
													map.put("big", asList.get(0) + "元/" + userTime + "小时,押金:"
															+ cashPledge + "元");
													map.put("medium", asList.get(1) + "元/" + userTime + "小时,押金:"
															+ cashPledge + "元");
													map.put("small", asList.get(2) + "元/" + userTime + "小时,押金:"
															+ cashPledge + "元");

												}
												map.put("jump", "3");
												map.put("pagejump", "300");
												map.put("caseNo", caseNo);
												map.put("isBandMobile", isBandMobile);
												map.put("hzmessageyy",
														"大柜：" + asList.get(0) + "元/" + userTime + "小时；" + "中柜:"
																+ asList.get(1) + "元/" + userTime + "小时；" + "小柜:"
																+ asList.get(2) + "元/" + userTime + "小时；" + "押金:"
																+ cashPledge + "元");
											} else { // 区分大中小柜但是没有设置价格
												map.put("jump", "0");
												map.put("pagejump", "500");
												map.put("hzmessageyy", "系统错误，请联系管理员！！!");
											}
										} else if (Byte.valueOf("2").equals(payType)) {// 区分大小柜且收费形式为计次
											if (StringUtils.isNotBlank(priceSize)) { // 大中小柜子价格
												List<String> asList = Arrays.asList(priceSize.split(","));

												if (Byte.valueOf("2").equals(payTime)) { // 使用前收费

													map.put("big", asList.get(0) + "元/次" + ",需要预先支付一个最低使用费用"
															+ asList.get(0) + "元,押金:" + cashPledge + "元");
													map.put("medium", asList.get(1) + "元/次" + ",需要预先支付一个最低使用费用"
															+ asList.get(1) + "元,押金:" + cashPledge + "元");
													map.put("small", asList.get(2) + "元/次" + ",需要预先支付一个最低使用费用"
															+ asList.get(2) + "元,押金:" + cashPledge + "元");
												} else {

													map.put("big", asList.get(0) + "元/次,押金:" + cashPledge + "元");
													map.put("medium", asList.get(1) + "元/次,押金:" + cashPledge + "元");
													map.put("small", asList.get(2) + "元/次,押金:" + cashPledge + "元");
												}

												map.put("jump", "3");
												map.put("pagejump", "300");
												map.put("caseNo", caseNo);
												map.put("isBandMobile", isBandMobile);
												map.put("hzmessageyy",
														"大柜：" + asList.get(0) + "元/次；" + "中柜:" + asList.get(1) + "元/次；"
																+ "小柜:" + asList.get(2) + "元/次；押金:" + cashPledge + "元");
											} else {
												map.put("jump", "0");
												map.put("pagejump", "500");
												map.put("hzmessageyy", "系统错误，请联系管理员！！!");
											}
										}
									}
								} else {
									map.put("jump", "0");
									map.put("pagejump", "500");
									map.put("hzmessageyy", "系统参数配置错误，请联系管理员！！!");
								}
							} else {
								map.put("jump", "0");
								map.put("pagejump", "500");
								map.put("hzmessageyy", "系统参数配置错误，请联系管理员！！!");
							}

						}

					}

				} else {
					map.put("jump", "0");
					map.put("pagejump", "500");
					map.put("hzmessageyy", "该设备异常，请联系管理员！");
				}
			} else {
				map.put("jump", "0");
				map.put("pagejump", "500");
				map.put("hzmessageyy", "该储物柜未连接网络，暂不能操作，请联系门店管理员处理!");
			}

		}
		return map;
	}





	/**
	 * @author liuCheng
	 * @since 2019年1月9日 下午1:08:08
	 * @param openId
	 * @throws Exception
	 *             获取用户资金余额
	 */
	@RequestMapping("/getAmount")
	@ResponseBody
	public Map<String, Object> getAmount(String openId) {
		Map<String, Object> map = new HashMap<>();
		CustomersAmountExample example = new CustomersAmountExample();
		example.createCriteria().andOpenIdEqualTo(openId);

		List<CustomersAmount> selectByExample = customersAmountMapper.selectByExample(example); // 查询用户资金余额  from customers_amount where openId =

		if (!selectByExample.isEmpty()) {
			BigDecimal totalAmount = selectByExample.get(0).getTotalAmount(); // 账户余额
			double doubleValue = totalAmount.doubleValue();
			String formatNumberCN = NumberHelper.formatNumberCN(doubleValue, NumberHelper.NUMBER_IN_2_0); //转为两位小数显示
			map.put("amount", formatNumberCN);
		}
		return map;
	}

	/**
	 * @author 刘成
	 * @since 2018年10月15日
	 * @param caseNo mac地址
	 * @param size 柜子大小
	 * @return 返回可以开启的门牌号
	 * @throws Exception
	 *             可以开启的柜子的列表
	 */
	@RequestMapping("/boxList")
	@ResponseBody
	public List<Integer> boxList(String caseNo, Byte size) throws Exception {
		log.info("可以开启的柜子的列表: caseNo:" + caseNo + " size:" + size);

		ManageCaseBoxExample example = new ManageCaseBoxExample();
		example.createCriteria().andCaseNoEqualTo(caseNo).andSizeEqualTo(size).andIsDelEqualTo((byte) 0)
				.andSwitchStatusEqualTo((byte) 1).andUseStatusEqualTo((byte) 0).andIsConnEqualTo((byte) 1);

		List<ManageCaseBox> selectByExample = manageCaseBoxMapper.selectByExample(example); //form manage_case_box where CASE_NO = and  SIZE = size and IS_DEL = 0 SWITCH_STATUS = 1 USE_STATUS = 0 IS_CONN = 1

		List<Integer> collect = selectByExample.stream()
				.collect(Collectors.mapping(ManageCaseBox::getDoorNum, Collectors.toList()));
		log.info("可以使用的门数个数为：" + collect.size());
		return collect;
	}

	/**
	 * @author 刘成
	 * @since 2018年10月15日
	 * @param caseNo
	 * @param openId
	 * @return
	 * @throws Exception
	 *             开箱（存物） pagejump：兼容上一个版本的处理 jump ： 500---弹窗返回首页
	 *             100---弹窗然后请求取物接口（取物） 200----弹窗不跳转 300--跳转充值页面 --800 跳转支付
	 */
	// 如果需要押金，则除了免费不需要押金外，其它都需要，生成订单支付成功后，把押金放入customers_amount表中
	// 在完成使用后去该表中查看是否有押金，有则退（超时时从押金中扣出相应部分）
	@RequestMapping("/openbox")
	@ResponseBody
	public Map<String, String> openbox(String caseNo, String openId, Integer doorNum, String password)
			throws Exception {
		log.info("caseNo:" + caseNo + " openId:" + openId + " doorNum:" + doorNum + " password:" + password);
		Map<String, String> map = new HashMap<>();
		Date date = new Date();
		// 查询储物柜详情
		ManageCaseExample manageCaseExample = new ManageCaseExample();
		manageCaseExample.createCriteria().andCaseNoEqualTo(caseNo);
		List<ManageCase> manageCaseList = manageCaseMapper.selectByExample(manageCaseExample);
		if (!manageCaseList.isEmpty()) {
			log.info("查询储物柜详情");
			ManageCase manageCase = manageCaseList.get(0);
			Integer typeId = manageCase.getTypeId();
			if (null != typeId) {
				log.info("查询储物柜type");
				Integer clearHour = manageCase.getClearHour();
				// 查询收费的详情
				ManageCaseType manageCaseType = manageCaseTypeMapper.selectByPrimaryKey(typeId);
				if (null != manageCaseType) {
					Byte payType = manageCaseType.getPayType();// 0，免费 1.计时 2.记次
					Byte isBindMobile = manageCaseType.getIsBindMobile();// 0.不需要绑定 1.需要
					if (Byte.valueOf("1").equals(isBindMobile)) {// 密码不能为空
						if (password == null || "".equals(password)) {
							map.put("pagejump", "500");
							map.put("message", "密码不能为空！");
							return map;
						}
						// 获取手机号
						MobileBindKeyExample mbkExample = new MobileBindKeyExample();
						mbkExample.createCriteria().andOpenIdEqualTo(openId);
						List<MobileBindKey> mbkms = mobileBindKeyMapper.selectByExample(mbkExample);
						if (mbkms.isEmpty()) {
							map.put("pagejump", "500");
							map.put("message", "您未绑定手机！");
							return map;
						}
						// 密码改为手机号后四位加密码
						password += mbkms.get(0).getPhone().substring(7, 11);
					}
					// 查询是否已经在使用了
					ManageCaseBoxExample caseBoxxample = new ManageCaseBoxExample();
					caseBoxxample.createCriteria().andCaseNoEqualTo(caseNo).andUserIdEqualTo(openId)
							.andIsDelEqualTo((byte) 0).andUseStatusEqualTo((byte) 1);
					List<ManageCaseBox> manageCaseBoxList = manageCaseBoxMapper.selectByExample(caseBoxxample);
					if (!manageCaseBoxList.isEmpty()) {// 使用中
						log.info("柜子使用中。。。");
						ManageCaseBox manageCaseBox = manageCaseBoxList.get(0);
						Integer doorNum2 = manageCaseBox.getDoorNum();
						if (Byte.valueOf("0").equals(payType)) {// 免费的
							log.info("免费的type");
							map.put("pagejump", "0");
							map.put("jump", "100");
							map.put("message", "查询到你已经使用了储物柜的" + doorNum2 + "号箱门，点击确定，即可开启箱门,谢谢您的支持！！!");
						} else {
							log.info("收费的type");
							map.put("pagejump", "0");
							map.put("jump", "100");
							map.put("message", "查询到你已经使用了储物柜的" + doorNum2 + "号箱，点击确定，我们会为你生成账单,谢谢您的支持！！!");
						}
					} else {// 未使用
						// 查询账户信息
						log.info("柜子未使用，查询账户信息");
						BigDecimal cashPledge = manageCaseType.getCashPledge();
						CustomersAmountExample customersAmountExample = new CustomersAmountExample();
						customersAmountExample.createCriteria().andOpenIdEqualTo(openId);
						List<CustomersAmount> customersAmountList = customersAmountMapper
								.selectByExample(customersAmountExample);
						if (!customersAmountList.isEmpty()) {
							log.info("已查询到账户信息");
							CustomersAmount customersAmount = customersAmountList.get(0);
							BigDecimal totalAmount = customersAmount.getTotalAmount();
							if (totalAmount.doubleValue() >= 0) {
								// 查询这个箱门还在不在
								log.info("查询储物柜是否还在");
								ManageCaseBoxExample caseBoxExample = new ManageCaseBoxExample();
								caseBoxExample.createCriteria().andCaseNoEqualTo(caseNo).andDoorNumEqualTo(doorNum)
										.andIsDelEqualTo((byte) 0).andUseStatusEqualTo((byte) 0);
								List<ManageCaseBox> manageCaseBoxList2 = manageCaseBoxMapper
										.selectByExample(caseBoxExample);
								if (manageCaseBoxList2.isEmpty()) {// 没有了
									log.info("该储物柜没有了");
									map.put("pagejump", "1");
									map.put("jump", "200");
									map.put("message", "开启失败，你选择的箱子已被他人抢走了，请重新选择！");
								} else {// 还在
									log.info("该储物柜还在");
									ManageCaseBox manageCaseBox = manageCaseBoxList2.get(0);
									Byte payTime = manageCaseType.getPayTime();
									if (Byte.valueOf("0").equals(payType)) {// 免费的，直接开门
										log.info("该储物柜免费");
										map = openDoorBySaveAndNoPay(doorNum, caseNo, manageCaseBox, openId, clearHour,
												payType, payTime, password);
									} else {
										log.info("该储物柜需要费用");
										if (Byte.valueOf("2").equals(payTime)) { // 2.使用前收费(押金+费用)
											log.info("使用前收费");
											// 使用前收费，，，，首先需要先将此储物箱的状态修改为使用中
											ManageCaseBox manageCaseBox1 = new ManageCaseBox();
											manageCaseBox1.setUseStatus((byte) 1);
											manageCaseBox1.setSaveTime(date);
											manageCaseBox1.setUserId("123");
											manageCaseBox1.setVersion(manageCaseBox.getVersion() + 1);
											ManageCaseBoxExample manageCaseBoxExample1 = new ManageCaseBoxExample();
											manageCaseBoxExample1.createCriteria()
													.andVersionEqualTo(manageCaseBox.getVersion())
													.andIdEqualTo(manageCaseBox.getId());
											int updateByExampleSelective = manageCaseBoxMapper.updateByExampleSelective(manageCaseBox1, manageCaseBoxExample1);
											if (updateByExampleSelective != 0) {// 占用成功
												log.info("占用该储物柜。。。");
												double amount = 0;// 金额
												Byte isSize = manageCase.getIsSize();
												if (Byte.valueOf("0").equals(isSize)) {// 不区分大小柜
													log.info("该储物柜不区分大小");
													String price = manageCaseType.getPrice();
													amount = Double.valueOf(price);
												} else {
													log.info("该储物柜区分大小");
													Byte size = manageCaseBox.getSize();
													String priceSize = manageCaseType.getPriceSize();
													List<String> asList = Arrays.asList(priceSize.split(","));

													if (Byte.valueOf("1").equals(size)) {
														String string = asList.get(0);
														amount = Double.valueOf(string);
													} else if (Byte.valueOf("2").equals(size)) {
														String string = asList.get(1);
														amount = Double.valueOf(string);
													} else if (Byte.valueOf("3").equals(size)) {
														String string = asList.get(2);
														amount = Double.valueOf(string);
													}
												}

												if (amount > 0) {
													// 创建订单
													log.info("需要支付：" + amount);
													String nonce_str = DictionaryUtils.getRandomStr();
													String out_trade_no = "XF_YF_ali" + new Date().getTime()+ nonce_str.substring(0, 2);// 商户订单号,64个字符以内、
													// 订单总金额，单位为元，精确到小数点后两位
													String place = manageCase.getPlace();
													String caseNoBuy = manageCase.getCaseNoBuy();
													String subject = place + "--" + caseNoBuy + "--" + doorNum + "--存";
													map = createPrepayOrder(nonce_str, out_trade_no, subject, amount,cashPledge, openId, manageCaseBox, password);
												} else {// 不用给钱直接开门存物
													log.info("不需要支付，直接开门");
													map = openDoorBySaveAndNoPay(doorNum, caseNo, manageCaseBox, openId,
															clearHour, payType, payTime, password);
												}

											} else {
												log.info("该储物柜已被抢。。。");
												map.put("pagejump", "1");
												map.put("jump", "200");
												map.put("message", "开启失败，你选择的箱子已被他人抢走了，请重新选择");
											}
										} else if(cashPledge.compareTo(BigDecimal.ZERO) == 1){// 1.使用后收费（先交押金）
											log.info("使用前收费");
											// 使用前收费，，，，首先需要先将此储物箱的状态修改为使用中
											ManageCaseBox manageCaseBox1 = new ManageCaseBox();
											manageCaseBox1.setUseStatus((byte) 1);
											manageCaseBox1.setSaveTime(date);
											manageCaseBox1.setUserId("123");
											manageCaseBox1.setVersion(manageCaseBox.getVersion() + 1);
											ManageCaseBoxExample manageCaseBoxExample1 = new ManageCaseBoxExample();
											manageCaseBoxExample1.createCriteria().andVersionEqualTo(manageCaseBox.getVersion()).andIdEqualTo(manageCaseBox.getId());
											int updateByExampleSelective = manageCaseBoxMapper.updateByExampleSelective(manageCaseBox1, manageCaseBoxExample1);
											if(updateByExampleSelective==0) {
												log.info("该储物柜已被抢。。。");
												map.put("pagejump", "1");
												map.put("jump", "200");
												map.put("message", "开启失败，你选择的箱子已被他人抢走了，请重新选择");
											}										
											// 创建订单
											log.info("创建订单");
											String nonce_str = DictionaryUtils.getRandomStr();
											String out_trade_no = "XF_YF_ali" + new Date().getTime()
													+ nonce_str.substring(0, 2);// 商户订单号,64个字符以内、
											// 订单总金额，单位为元，精确到小数点后两位
											String place = manageCase.getPlace();
											String caseNoBuy = manageCase.getCaseNoBuy();
											String subject = place + "--" + caseNoBuy + "--" + doorNum + "--存";
											map = createPledgeOrder(nonce_str, out_trade_no, subject, cashPledge,openId, manageCaseBox, password);
										}else{
											log.info("使用后收费,押金小于0，直接开门！");
											map = openDoorBySaveAndNoPay(doorNum, caseNo, manageCaseBox, openId, clearHour,payType, payTime, password);
										}
									}
								}
							} else {
								map.put("pagejump", "3");
								map.put("jump", "300");
								map.put("message", "您已欠费，请充值后再使用");
							}

						} else {
							log.info("未能查询用户账户信息");
							map.put("pagejump", "500");
							map.put("message", "获取登陆失败,请重试");
						}
					}
				} else {
					log.info("manageCaseType为空！");
					map.put("pagejump", "500");
					map.put("message", "系统错误请重试！");
				}
			} else {
				log.info("Integer typeId = manageCase.getTypeId()为空！");
				map.put("pagejump", "500");
				map.put("message", "系统错误请重试！");
			}
		} else {
			log.info("manageCaseList.isEmpty()");
			map.put("pagejump", "500");
			map.put("message", "系统错误请重试！");

		}
		return map;
	}

	/**
	 * @author 刘成
	 * @param openId 微信用户唯一标识
	 * @param caseNo mac地址
	 * @throws Exception
	 * @since 2018年10月15日 取物
	 */
	@RequestMapping("/openMyBox")
	@ResponseBody
	public Map<String, Object> openMyBox(String openId, String caseNo) throws Exception {
		Map<String, Object> returnMap = new HashMap<>();
		int doorNum = 0;

		// 1.计算金额，生成账单
		// 1.1查询用户使用的储物柜的类别，，，是否区分大小柜
		ManageCaseExample caseExample = new ManageCaseExample();
		caseExample.createCriteria().andCaseNoEqualTo(caseNo);
		List<ManageCase> selectByExample2 = manageCaseMapper.selectByExample(caseExample); // from manage_case where CASE_NO = caseNo
		ManageCase manageCase = selectByExample2.get(0); // 获取到mac地址对应的柜子信息

		// 1.2查询到用户使用的箱子
		ManageCaseBoxExample example = new ManageCaseBoxExample();
		example.createCriteria().andCaseNoEqualTo(caseNo).andIsDelEqualTo((byte) 0).andUserIdEqualTo(openId)
				.andUseStatusEqualTo((byte) 1);
		List<ManageCaseBox> selectByExample = manageCaseBoxMapper.selectByExample(example); //from manage_case_box where CASE_NO = caseNo and IS_DEL = 0 and USER_ID = openId and USE_STATUS = 1

		if (!selectByExample.isEmpty()) {
			// 这里的处理逻辑：计算出还需要支付的钱，如果没有就直接打开箱子，如果有则获取押金，从押金里扣除，如果还有剩余押金则退押金，不够则继续支付剩下的钱
			// 正在使用的箱子信息
			ManageCaseBox manageCaseBox = selectByExample.get(0);
			Integer id = manageCaseBox.getId(); // 箱子主键
			Integer typeId = manageCase.getTypeId(); // 收费类型id
			doorNum = manageCaseBox.getDoorNum(); // 几号门
			ManageCaseType selectByPrimaryKey = manageCaseTypeMapper.selectByPrimaryKey(typeId); // 收费类型信息

			// 使用后支付或超时需要支付的钱 -- 会返回存物的费用
			double amount = CustomersAmountCount.getAliCharge(manageCaseBox, manageCase, selectByPrimaryKey);

			BigDecimal pledge = BigDecimal.ZERO;// 初始化为0
			CustomersAmountExample customersAmountExample = new CustomersAmountExample();
			customersAmountExample.createCriteria().andOpenIdEqualTo(openId); // from customers_amount where OPEN_ID =
			List<CustomersAmount> list = customersAmountMapper.selectByExample(customersAmountExample); // 查询出此用户对应的账户信息
			if (!list.isEmpty()) {
				CustomersAmount ca = list.get(0);
				if (Byte.valueOf("1").equals(ca.getIsPay())) {// 已经缴纳押金 是否缴纳押金（0.否    1.是  2.退款中  3.退款失败）
					pledge = ca.getAssureAmount();// 获取押金
				}
			}
			if (amount == 0) {
				log.info("不需要额外从押金中扣费。。。。");
				returnMap = openMyCommonBoxByXcxAndNoPay(manageCaseBox, openId, doorNum);
				return returnMap;
			}

			BigDecimal cost = BigDecimal.ZERO;
			//判断押金是否为0，0则不需要从押金扣除，也就不需要将扣除的押金写入账单
			if(pledge.compareTo(BigDecimal.ZERO) == 1){//大于0，有押金
				//判断费用是否大于押金,大于押金则:写入账单值取押金值,超出部分金额会从新支付并生成账单
				cost = new BigDecimal(amount);
				if(cost.compareTo(pledge) == 1){cost = pledge;} // a<b, 返回-1 a=b，返回0 a>b, 返回1
			}
			amount = pledge.subtract(new BigDecimal(amount + "")).doubleValue(); // 押金减去费用
			
			if (amount < 0) {  // 小于0 说明费用高于押金 需要扣除押金 并且支付多余的费用会调用支付宝
				// 需要支付，支付成功，清空押金
				amount = Math.abs(amount); // 绝对值 也就是正数
				String nonce_str = DictionaryUtils.getRandomStr(); // 随机字符串
				String out_trade_no = "XF_ali" + new Date().getTime() + nonce_str.substring(0, 2);// 商户订单号,64个字符以内、
				// 订单总金额，单位为元，精确到小数点后两位
				String place = manageCase.getPlace(); //储物柜位置
				String caseNoBuy = manageCase.getCaseNoBuy(); // 商家自己所输入的编号
				String subject = place + "--" + caseNoBuy + "--" + doorNum + "--取";
				Map<String, Object> map = new HashMap<>();
				map.put("out_trade_no", out_trade_no);
				map.put("total_amount", amount);
				map.put("subject", subject);
				map.put("buyer_id", openId);
				map.put("timeout_express", "2m");
				String jsonString = JSONObject.toJSONString(map); //序列化为json
				AlipayClient alipayClient = new DefaultAlipayClient(AliConfig.URL, AliConfig.APP_ID,
						AliConfig.PRIVATE_KEY, "JSON", "UTF-8", AliConfig.ALIPAY_PUBLIC_KEY, "RSA2");
				AlipayTradeCreateRequest request = new AlipayTradeCreateRequest();
				// 异步通知接口
				request.setNotifyUrl(AliConfig.DOMAIN_URL + "/alixcxCommon/paySucessToOpen"); // 支付宝回调接口
				request.setBizContent(jsonString);
				AlipayTradeCreateResponse response = alipayClient.execute(request); // 发送

				if (response.isSuccess()) { // 成功
					String tradeNo = response.getTradeNo(); // 交易号
					// 将订单号插入数据库
					PayOrder record = new PayOrder();
					record.setCreartTime(new Date());
					record.setIsPay((byte) 0); // 是否完成支付 1 是 0否
					record.setOpenId(openId);
					record.setOutTradeNo(out_trade_no); // 商户订单号
					Double money = amount * 100; //以分为单位来存储
					record.setTotalFee(money.intValue()); // 费用
					record.setTransactionId(tradeNo); // 交易号
					record.setBoxId(id); // 箱子主键
					payOrderMapper.insertSelective(record); // insert into pay_order
					returnMap.put("code", "300");
					returnMap.put("doorNum", doorNum);
					returnMap.put("tradeNo", tradeNo);
				} else {
					returnMap.put("code", "400");
					returnMap.put("openboxMessage", "系统错误，请重试");
				}
			} else if (amount > 0) { // 大于0 则表示 押金大于费用
				// 扣除了费用 把剩余的押金放入customers_Amount表中
				// refund(openId, pledge);
				customersAmountService.setPledge(openId, new BigDecimal(amount + ""));
				returnMap = openMyCommonBoxByXcxAndNeedPay(manageCaseBox, openId, doorNum, cost); // 开箱操作
				returnMap.put("doorNum", doorNum);
			} else { // 费用和押金一样  直接清空押金 开门
				customersAmountService.clearPledge(openId); // 清空押金
				returnMap = openMyCommonBoxByXcxAndNeedPay(manageCaseBox, openId, doorNum, cost); // 开门
				returnMap.put("doorNum", doorNum);
			}
		}
		return returnMap;
	}

	/**
	 * @author liuCheng
	 * @since 2018年12月21日 下午4:18:57
	 * @param openId
	 * @param caseNo
	 * @return
	 * @throws Exception
	 *             中途取件
	 */
	@RequestMapping("/openMyBoxMidWay")
	@ResponseBody
	public Map<String, Object> openMyBoxMidWay(String openId, String caseNo) throws Exception {
		Map<String, Object> returnMap = new HashMap<>();
		int doorNum = 0;
		// 1.计算金额，生成账单
		// 1.1查询用户使用的储物柜的类别，，，是否区分大小柜
		ManageCaseExample caseExample = new ManageCaseExample();
		caseExample.createCriteria().andCaseNoEqualTo(caseNo);
		List<ManageCase> selectByExample2 = manageCaseMapper.selectByExample(caseExample);
		ManageCase manageCase = selectByExample2.get(0);
		// 1.2查询到用户使用的箱子
		ManageCaseBoxExample example = new ManageCaseBoxExample();
		example.createCriteria().andCaseNoEqualTo(caseNo).andIsDelEqualTo((byte) 0).andUserIdEqualTo(openId)
				.andUseStatusEqualTo((byte) 1);
		List<ManageCaseBox> selectByExample = manageCaseBoxMapper.selectByExample(example);
		if (!selectByExample.isEmpty()) {
			ManageCaseBox manageCaseBox = selectByExample.get(0);
			Integer id = manageCaseBox.getId();
			Integer typeId = manageCase.getTypeId();
			doorNum = manageCaseBox.getDoorNum();
			// 中途取件是否重计费
			if (manageCase != null) {
				Integer caseType = manageCase.getTypeId();
				ManageCaseType manageCaseType = manageCaseTypeMapper.selectByPrimaryKey(caseType);
				if (manageCaseType != null && Byte.valueOf("0").equals(manageCaseType.getIsHalfwayRestart())) {
					// 不需要重新计费
					returnMap = openMyCommonBoxByXcxAndNoPayMidWay(manageCaseBox, openId, doorNum);
					return returnMap;
				}
			}
			ManageCaseType selectByPrimaryKey = manageCaseTypeMapper.selectByPrimaryKey(typeId);

			double amount = CustomersAmountCount.getMidWayAliCharge(manageCaseBox, manageCase, selectByPrimaryKey);

			// 2.支付宝发起支付请求
			// 调用支付宝的统一生成订单接口
			if (amount > 0) {
				String nonce_str = DictionaryUtils.getRandomStr();
				String out_trade_no = "XF_ali" + new Date().getTime() + nonce_str.substring(0, 2);// 商户订单号,64个字符以内、
				// 订单总金额，单位为元，精确到小数点后两位
				String place = manageCase.getPlace();
				String caseNoBuy = manageCase.getCaseNoBuy();
				String subject = place + "--" + caseNoBuy + "--" + doorNum + "--中途取件";
				Map<String, Object> map = new HashMap<>();
				map.put("out_trade_no", out_trade_no);
				map.put("total_amount", amount);
				map.put("subject", subject);
				map.put("buyer_id", openId);
				map.put("timeout_express", "2m");
				String jsonString = JSONObject.toJSONString(map);
				AlipayClient alipayClient = new DefaultAlipayClient(AliConfig.URL, AliConfig.APP_ID,
						AliConfig.PRIVATE_KEY, "JSON", "UTF-8", AliConfig.ALIPAY_PUBLIC_KEY, "RSA2");
				AlipayTradeCreateRequest request = new AlipayTradeCreateRequest();
				// 异步通知接口
				request.setNotifyUrl(AliConfig.DOMAIN_URL + "/alixcxCommon/paySucessToMidWay");
				request.setBizContent(jsonString);
				AlipayTradeCreateResponse response = alipayClient.execute(request);

				if (response.isSuccess()) {
					String tradeNo = response.getTradeNo();
					// 将订单号插入数据库
					PayOrder record = new PayOrder();
					record.setCreartTime(new Date());
					record.setIsPay((byte) 0);
					record.setOpenId(openId);
					record.setOutTradeNo(out_trade_no);
					Double money = amount * 100;
					record.setTotalFee(money.intValue());
					record.setTransactionId(tradeNo);
					record.setBoxId(id);
					payOrderMapper.insertSelective(record);
					returnMap.put("code", "200");
					returnMap.put("doorNum", doorNum);
					returnMap.put("tradeNo", tradeNo);
				} else {
					returnMap.put("code", "400");
					returnMap.put("openboxMessage", "系统错误，请重试");
				}
			} else {// 直接开柜
				returnMap = openMyCommonBoxByXcxAndNoPayMidWay(manageCaseBox, openId, doorNum);
				return returnMap;
			}
		}
		return returnMap;
	}

	/**
	 * @author liuCheng
	 * @since 2019年1月4日 下午2:06:44
	 * @param boxId
	 * @param openId
	 * @return
	 * @throws Exception
	 *             用户自己清除
	 */
	@RequestMapping("/clearByOneself")
	@ResponseBody
	public Map<String, Object> clearByOneself(Integer boxId, String openId) throws Exception {
		Map<String, Object> map = new HashMap<>();
		ManageCaseBoxExample example = new ManageCaseBoxExample();
		example.createCriteria().andIdEqualTo(boxId).andUserIdEqualTo(openId).andUseStatusEqualTo((byte) 1);
		List<ManageCaseBox> selectByExample = manageCaseBoxMapper.selectByExample(example);
		if (selectByExample.isEmpty()) {
			map.put("code", "401");// 没有此储物柜
			return map;
		}
		try {
			ManageCaseBox manageCaseBox = selectByExample.get(0);
			int id = manageCaseBox.getId();
			Integer doorNum = manageCaseBox.getDoorNum();
			String caseNo = manageCaseBox.getCaseNo();
			ManageCaseExample caseExample = new ManageCaseExample();
			caseExample.createCriteria().andCaseNoEqualTo(caseNo);
			List<ManageCase> caseList = manageCaseMapper.selectByExample(caseExample);
			ManageCase manageCase = caseList.get(0);
			Integer typeId = manageCase.getTypeId();
			ManageCaseType manageCaseType = manageCaseTypeMapper.selectByPrimaryKey(typeId);
			Byte source = AllConst.ACCESS_RECORD_SOURCE.ALI_XCX_SOURCE;
			Byte type = AllConst.ACCESS_RECORD_TYPE.CLEAR_BY_OWN;
			// 使用后支付或超时需要支付的钱
			double amount = CustomersAmountCount.getAliCharge(manageCaseBox, manageCase, manageCaseType);
			BigDecimal pledge = BigDecimal.ZERO;// 初始化为0
			CustomersAmountExample customersAmountExample = new CustomersAmountExample();
			customersAmountExample.createCriteria().andOpenIdEqualTo(openId);
			List<CustomersAmount> list = customersAmountMapper.selectByExample(customersAmountExample);
			if (!list.isEmpty()) {
				CustomersAmount ca = list.get(0);
				if (Byte.valueOf("1").equals(ca.getIsPay())) {// 已经缴纳押金
					pledge = ca.getAssureAmount();// 获取押金
				}
			}
			if (amount == 0) {
				log.info("不需要额外从押金中扣费。。。。");
				manageCaseBoxService.clearByOneself(manageCaseBox, manageCase, manageCaseType, source, type);
				map.put("code", "200");
				return map;
			}
			
			BigDecimal cost = BigDecimal.ZERO;
			//判断押金是否为0，0则不需要从押金扣除，也就不需要将扣除的押金写入账单
			if(pledge.compareTo(BigDecimal.ZERO) == 1){//大于0，有押金
				//判断费用是否大于押金,大于押金则:写入账单值取押金值,超出部分金额会从新支付并生成账单
				cost = new BigDecimal(amount);
				if(cost.compareTo(pledge) == 1){cost = pledge;}
			}
			
			amount = pledge.subtract(new BigDecimal(amount + "")).doubleValue();

			if (amount < 0) {
				amount = Math.abs(amount);
				// 需要支付，支付成功，清空押金
				String nonce_str = DictionaryUtils.getRandomStr();
				String out_trade_no = "XF_ali" + new Date().getTime() + nonce_str.substring(0, 2);// 商户订单号,64个字符以内、
				// 订单总金额，单位为元，精确到小数点后两位
				String place = manageCase.getPlace();
				String caseNoBuy = manageCase.getCaseNoBuy();
				String subject = place + "--" + caseNoBuy + "--" + doorNum + "--取";
				map.put("out_trade_no", out_trade_no);
				map.put("total_amount", Math.abs(amount));// 这里为绝对值
				map.put("subject", subject);
				map.put("buyer_id", openId);
				map.put("timeout_express", "2m");
				String jsonString = JSONObject.toJSONString(map);
				AlipayClient alipayClient = new DefaultAlipayClient(AliConfig.URL, AliConfig.APP_ID,
						AliConfig.PRIVATE_KEY, "JSON", "UTF-8", AliConfig.ALIPAY_PUBLIC_KEY, "RSA2");
				AlipayTradeCreateRequest request = new AlipayTradeCreateRequest();
				// 异步通知接口
				request.setNotifyUrl(AliConfig.DOMAIN_URL + "/alixcxCommon/clearPaySucess");
				request.setBizContent(jsonString);
				AlipayTradeCreateResponse response = alipayClient.execute(request);

				if (response.isSuccess()) {
					String tradeNo = response.getTradeNo();
					// 将订单号插入数据库
					PayOrder record = new PayOrder();
					record.setCreartTime(new Date());
					record.setIsPay((byte) 0);
					record.setOpenId(openId);
					record.setOutTradeNo(out_trade_no);
					Double money = amount * 100;
					record.setTotalFee(money.intValue());
					record.setTransactionId(tradeNo);
					record.setBoxId(id);
					payOrderMapper.insertSelective(record);
					map.put("code", "300");
					map.put("doorNum", doorNum);
					map.put("tradeNo", tradeNo);
				} else {
					map.put("code", "400");
					map.put("openboxMessage", "系统错误，请重试");
				}
				return map;
			} else if (amount > 0) {
				// 退回该金额，清空押金
				manageCaseBoxService.clearByOneself(manageCaseBox, manageCase, manageCaseType, source, type, cost);
				customersAmountService.setPledge(openId, new BigDecimal(amount + ""));
				map.put("code", "200");
				map.put("doorNum", doorNum);
				return map;
			} else {
				// 清空押金,直接开门
				manageCaseBoxService.clearByOneself(manageCaseBox, manageCase, manageCaseType, source, type, cost);
				customersAmountService.clearPledge(openId);
				map.put("code", "100");
				return map;
			}
		} catch (Exception e) {
			map.put("code", "500");// 清除失败请重试
			return map;
		}
	}

	/**
	 * @author liuCheng
	 * @since 2019年1月4日 下午3:13:44
	 * @param boxId
	 * @param openId
	 * @return
	 * @throws Exception
	 *             续费使用
	 */
	@RequestMapping("/continueUsing")
	@ResponseBody
	public Map<String, Object> continueUsing(Integer boxId, String openId) throws Exception {
		Map<String, Object> returnMap = new HashMap<>();
		ManageCaseBoxExample example = new ManageCaseBoxExample();
		example.createCriteria().andIdEqualTo(boxId).andUserIdEqualTo(openId).andUseStatusEqualTo((byte) 1);
		List<ManageCaseBox> selectByExample = manageCaseBoxMapper.selectByExample(example);
		if (!selectByExample.isEmpty()) {
			ManageCaseBox manageCaseBox = selectByExample.get(0);
			Integer doorNum = manageCaseBox.getDoorNum();
			String caseNo = manageCaseBox.getCaseNo();
			ManageCaseExample caseExample = new ManageCaseExample();
			caseExample.createCriteria().andCaseNoEqualTo(caseNo);
			List<ManageCase> manageCaseList = manageCaseMapper.selectByExample(caseExample);
			ManageCase manageCase = manageCaseList.get(0);
			Integer typeId = manageCase.getTypeId();
			ManageCaseType manageCaseType = manageCaseTypeMapper.selectByPrimaryKey(typeId);
			Byte payType = manageCaseType.getPayType();
			double amount = 0;
			// 查询使用费用
			// 插入继续使用的记录信息
			// 修改储物柜的使用时间、结束时间、
			if (Byte.valueOf("0").equals(payType)) {// 免费的若需要继续使用，需支付一定的费用
				SysConstExample sysExample = new SysConstExample();
				sysExample.createCriteria().andNameEqualTo(AppConfig.FREE_TIMEOUT);
				List<SysConst> sysConst = sysConstMapper.selectByExample(sysExample);
				String value = sysConst.get(0).getValue();
				amount = Double.valueOf(value);
			} else {// 非免费的支付相应的费用---与中途取物计算方式一样
				amount = CustomersAmountCount.getMidWayAliCharge(manageCaseBox, manageCase, manageCaseType);
			}
			if (amount > 0) {
				String nonce_str = DictionaryUtils.getRandomStr();
				String out_trade_no = "XF_ali_con" + new Date().getTime() + nonce_str.substring(0, 2);// 商户订单号,64个字符以内、
				// 订单总金额，单位为元，精确到小数点后两位
				String place = manageCase.getPlace();
				String caseNoBuy = manageCase.getCaseNoBuy();
				String subject = place + "--" + caseNoBuy + "--" + doorNum + "--续费";
				String notifyUrl = AliConfig.DOMAIN_URL + "/alixcxCommon/continueUsingToPaySucess";

				AlipayTradeCreateResponse response = creatAliPay(subject, notifyUrl, amount, out_trade_no, openId);

				if (response.isSuccess()) {
					String tradeNo = response.getTradeNo();
					// 将订单号插入数据库
					Double money = amount * 100;
					PayOrder record = new PayOrder();
					record.setCreartTime(new Date());
					record.setIsPay((byte) 0);
					record.setOpenId(openId);
					record.setOutTradeNo(out_trade_no);
					record.setTotalFee(money.intValue());
					record.setTransactionId(tradeNo);
					record.setBoxId(boxId);
					payOrderMapper.insertSelective(record);
					returnMap.put("tradeNo", tradeNo);
					if (Byte.valueOf("0").equals(payType)) {
						returnMap.put("code", "889");// 免费的支付
					} else {
						returnMap.put("code", "888");// 支付
					}
				} else {
					returnMap.put("code", "444");// 无需现在续费
				}
			} else {
				returnMap.put("code", "401");// 没有使用此储物柜
			}
		}
		return returnMap;
	}

	/**
	 * @author liuCheng
	 * @since 2019年1月8日 上午9:59:30 使用中的储物柜
	 */
	@RequestMapping("/using")
	@ResponseBody
	public List<UsingBoxByXcxVO> using(String openId) {
		List<UsingBoxByXcxVO> list = new ArrayList<>();
		ManageCaseBoxExample example = new ManageCaseBoxExample();
		example.createCriteria().andUserIdEqualTo(openId).andIsDelEqualTo((byte) 0).andUseStatusEqualTo((byte) 1);
		List<ManageCaseBox> selectByExample = manageCaseBoxMapper.selectByExample(example);
		if (!selectByExample.isEmpty()) {
			selectByExample.forEach(a -> {
				UsingBoxByXcxVO usingBoxByXcxVO = new UsingBoxByXcxVO();
				usingBoxByXcxVO.setBoxId(a.getId());
				usingBoxByXcxVO.setDoorNum(a.getDoorNum());
				list.add(usingBoxByXcxVO);
			});
		}
		return list;
	}

	/**
	 * @author liuCheng
	 * @since 2019年1月8日 下午2:39:13
	 * 获取箱门的信息
	 * 
	 */
	@RequestMapping("/getUseBoxInfo")
	@ResponseBody
	public XcxUseBoxVO getUseBoxInfo(Integer boxId, String openId) {
		ManageCaseBoxExample caseBoxExample = new ManageCaseBoxExample();
		caseBoxExample.createCriteria().andIdEqualTo(boxId).andUserIdEqualTo(openId).andUseStatusEqualTo((byte) 1)
				.andIsDelEqualTo((byte) 0);
		List<ManageCaseBox> selectByExample = manageCaseBoxMapper.selectByExample(caseBoxExample);
		XcxUseBoxVO useBoxInfo = new XcxUseBoxVO();

		if (!selectByExample.isEmpty()) {
			ManageCaseBox manageCaseBox = selectByExample.get(0);
			String caseNo = manageCaseBox.getCaseNo();
			ManageCaseExample example = new ManageCaseExample();
			example.createCriteria().andCaseNoEqualTo(caseNo);
			List<ManageCase> manageCaseList = manageCaseMapper.selectByExample(example);
			ManageCase manageCase = manageCaseList.get(0);
			Integer clearHour = manageCase.getClearHour();
			String place = manageCase.getPlace();
			String caseNoBuy = manageCase.getCaseNoBuy();
			Integer doorNum = manageCaseBox.getDoorNum();
			Date saveTime = manageCaseBox.getSaveTime();
			Date clearBoxTime = manageCaseBox.getClearBoxTime(); // 超时时间
			String startTime = DateTimeHelper.formatDateTimetoString(saveTime, DateTimeHelper.FMT_yyyyMMddHHmmss);
			String endTime = DateTimeHelper.formatDateTimetoString(clearBoxTime, DateTimeHelper.FMT_yyyyMMddHHmmss);

			useBoxInfo.setCode(200);
			useBoxInfo.setCaseNum(caseNoBuy);
			useBoxInfo.setDoorNum(doorNum);
			useBoxInfo.setEndTime(endTime); //超时时间
			useBoxInfo.setPlace(place);
			useBoxInfo.setStartTime(startTime); // 使用时间
			useBoxInfo.setClearHour(clearHour);
		} else {
			useBoxInfo.setCode(400);
		}
		return useBoxInfo;
	}

	/**
	 * @author liuCheng
	 * @since 2018年11月7日 下午2:54:53
	 * @param request
	 * @return
	 * @throws Exception
	 *             续费完成后的异步通知
	 */
	@RequestMapping("/continueUsingToPaySucess")
	@ResponseBody
	public String continueUsingToPaySucess(HttpServletRequest request) throws Exception {
		String trade_no = request.getParameter("trade_no");
		String trade_status = request.getParameter("trade_status");
		String out_trade_no = request.getParameter("out_trade_no");
		String buyer_id = request.getParameter("buyer_id");
		String total_amount = request.getParameter("total_amount");
		BigDecimal amount = BigDecimal.valueOf(Double.valueOf(total_amount));

		if (StringUtils.isNotBlank("trade_status") && trade_status.equals("TRADE_SUCCESS")) {
			PayOrderExample example = new PayOrderExample();
			example.createCriteria().andIsPayEqualTo((byte) 0).andOpenIdEqualTo(buyer_id)
					.andTransactionIdEqualTo(trade_no).andOutTradeNoEqualTo(out_trade_no);
			List<PayOrder> selectByExample = payOrderMapper.selectByExample(example);
			if (!selectByExample.isEmpty()) {
				PayOrder payOrder = selectByExample.get(0);
				Integer boxId = payOrder.getBoxId();
				ManageCaseBox manageCaseBox = manageCaseBoxMapper.selectByPrimaryKey(boxId);
				Byte source = AllConst.ACCESS_RECORD_SOURCE.ALI_XCX_SOURCE;
				try {
					manageCaseBoxService.continueCommonCaseFinish(trade_no, amount, payOrder, manageCaseBox, source);
					return "success";
				} catch (Exception e) {
					return "";
				}
			} else {
				return "";
			}
		} else {
			return "";
		}

	}

	/**
	 * 支付宝回调接口
	 * @param request
	 * @return
	 * @throws Exception
	 */
	@RequestMapping("/paySucessToOpen")
	@ResponseBody
	public String paySucessToOpen(HttpServletRequest request) throws Exception {

		String trade_no = request.getParameter("trade_no");
		String trade_status = request.getParameter("trade_status");
		String out_trade_no = request.getParameter("out_trade_no");
		String buyer_id = request.getParameter("buyer_id");

		if (StringUtils.isNotBlank("trade_status") && trade_status.equals("TRADE_SUCCESS")) {
			PayOrderExample example = new PayOrderExample();
			example.createCriteria().andIsPayEqualTo((byte) 0).andOpenIdEqualTo(buyer_id)
					.andTransactionIdEqualTo(trade_no).andOutTradeNoEqualTo(out_trade_no);
			List<PayOrder> selectByExample = payOrderMapper.selectByExample(example);
			if (!selectByExample.isEmpty()) {
				Date date = new Date();
				PayOrder payOrder = selectByExample.get(0);
				Integer boxId = payOrder.getBoxId();

				ManageCaseBox manageCaseBox = manageCaseBoxMapper.selectByPrimaryKey(boxId);
				Integer doorNum = manageCaseBox.getDoorNum();
				String caseNo = manageCaseBox.getCaseNo();

				ManageCaseExample manageCaseExample = new ManageCaseExample();
				manageCaseExample.createCriteria().andCaseNoEqualTo(caseNo);
				List<ManageCase> selectByExample2 = manageCaseMapper.selectByExample(manageCaseExample);

				ManageCase manageCase = selectByExample2.get(0);

				Long time = 0l;
				Date saveTime = manageCaseBox.getSaveTime();
				time = date.getTime() - saveTime.getTime();

				try {
					customersAmountService.clearPledge(payOrder.getOpenId());// 清除押金
					manageCaseBoxService.payFinishByAliAndCommonBox(payOrder, manageCaseBox, manageCase, time);
				} catch (Exception e) {
					return "";
				}

				// 1.开门
				Connection connection = ConnectionUtils.getConnection();
				Channel channel = connection.createChannel();
				Map<String, Object> sendMap = new HashMap<>();
				sendMap.put("door", doorNum);
				sendMap.put("timestamp", date.getTime());
				ObjectMapper mapper = new ObjectMapper();
				Map<String, Object> args = new HashMap<String, Object>();
				args.put("x-message-ttl", 40000);
				channel.queueDeclare(caseNo, true, false, false, args);
				String writeValueAsString = mapper.writeValueAsString(sendMap);
				channel.basicPublish("", caseNo, null, writeValueAsString.getBytes());
				channel.close();
				connection.close();

				return "success";

			} else {
				return "";
			}
		} else {
			return "";
		}

	}

	@RequestMapping("/clearPaySucess")
	@ResponseBody
	public String clearPaySucess(HttpServletRequest request) throws Exception {

		String trade_no = request.getParameter("trade_no");
		String trade_status = request.getParameter("trade_status");
		String out_trade_no = request.getParameter("out_trade_no");
		String buyer_id = request.getParameter("buyer_id");

		if (StringUtils.isNotBlank("trade_status") && trade_status.equals("TRADE_SUCCESS")) {
			PayOrderExample example = new PayOrderExample();
			example.createCriteria().andIsPayEqualTo((byte) 0).andOpenIdEqualTo(buyer_id)
					.andTransactionIdEqualTo(trade_no).andOutTradeNoEqualTo(out_trade_no);
			List<PayOrder> selectByExample = payOrderMapper.selectByExample(example);
			if (!selectByExample.isEmpty()) {
				Date date = new Date();
				PayOrder payOrder = selectByExample.get(0);
				Integer boxId = payOrder.getBoxId();
				ManageCaseBox manageCaseBox = manageCaseBoxMapper.selectByPrimaryKey(boxId);
				String caseNo = manageCaseBox.getCaseNo();
				ManageCaseExample manageCaseExample = new ManageCaseExample();
				manageCaseExample.createCriteria().andCaseNoEqualTo(caseNo);
				List<ManageCase> selectByExample2 = manageCaseMapper.selectByExample(manageCaseExample);
				ManageCase manageCase = selectByExample2.get(0);
				Long time = 0l;
				Date saveTime = manageCaseBox.getSaveTime();
				time = date.getTime() - saveTime.getTime();

				try {
					Integer typeId = manageCase.getTypeId();
					ManageCaseType manageCaseType = manageCaseTypeMapper.selectByPrimaryKey(typeId);
					Byte source = AllConst.ACCESS_RECORD_SOURCE.ALI_XCX_SOURCE;
					Byte type = AllConst.ACCESS_RECORD_TYPE.CLEAR_BY_OWN;
					manageCaseBoxService.clearByOneself(manageCaseBox, manageCase, manageCaseType, source, type);
					manageCaseBoxService.clearPayFinishByAli(payOrder, manageCaseBox, manageCase, time);
					customersAmountService.clearPledge(payOrder.getOpenId());
				} catch (Exception e) {
					return "";
				}
				return "success";
			} else {
				return "";
			}
		} else {
			return "";
		}

	}

	/**
	 * @author liuCheng
	 * @since 2018年12月21日 下午4:37:39
	 * @param request
	 * @return
	 * @throws Exception
	 *             中途取物支付完成后的---异步处理
	 */
	@RequestMapping("/paySucessToMidWay")
	@ResponseBody
	public String paySucessToMidWay(HttpServletRequest request) throws Exception {
		String trade_no = request.getParameter("trade_no");
		String trade_status = request.getParameter("trade_status");
		String out_trade_no = request.getParameter("out_trade_no");
		String buyer_id = request.getParameter("buyer_id");

		if (StringUtils.isNotBlank("trade_status") && trade_status.equals("TRADE_SUCCESS")) {
			PayOrderExample example = new PayOrderExample();
			example.createCriteria().andIsPayEqualTo((byte) 0).andOpenIdEqualTo(buyer_id)
					.andTransactionIdEqualTo(trade_no).andOutTradeNoEqualTo(out_trade_no);
			List<PayOrder> selectByExample = payOrderMapper.selectByExample(example);
			if (!selectByExample.isEmpty()) {
				Date date = new Date();
				PayOrder payOrder = selectByExample.get(0);
				Integer boxId = payOrder.getBoxId();

				ManageCaseBox manageCaseBox = manageCaseBoxMapper.selectByPrimaryKey(boxId);
				Integer doorNum = manageCaseBox.getDoorNum();
				String caseNo = manageCaseBox.getCaseNo();

				ManageCaseExample manageCaseExample = new ManageCaseExample();
				manageCaseExample.createCriteria().andCaseNoEqualTo(caseNo);
				List<ManageCase> selectByExample2 = manageCaseMapper.selectByExample(manageCaseExample);

				ManageCase manageCase = selectByExample2.get(0);

				Long time = 0l;
				Date saveTime = manageCaseBox.getSaveTime();
				time = date.getTime() - saveTime.getTime();

				try {
					// customersAmountService.clearPledge(payOrder.getOpenId());
					manageCaseBoxService.payFinishByAliAndCommonBoxMidWay(payOrder, manageCaseBox, manageCase, time);
				} catch (Exception e) {
					return "";
				}

				// 1.开门
				Connection connection = ConnectionUtils.getConnection();
				Channel channel = connection.createChannel();
				Map<String, Object> sendMap = new HashMap<>();
				sendMap.put("door", doorNum);
				sendMap.put("timestamp", date.getTime());
				ObjectMapper mapper = new ObjectMapper();
				Map<String, Object> args = new HashMap<String, Object>();
				args.put("x-message-ttl", 40000);
				channel.queueDeclare(caseNo, true, false, false, args);
				String writeValueAsString = mapper.writeValueAsString(sendMap);
				channel.basicPublish("", caseNo, null, writeValueAsString.getBytes());
				channel.close();
				connection.close();

				return "success";

			} else {
				return "";
			}
		} else {
			return "";
		}

	}

	// Prepay
	/**
	 * @author liuCheng
	 * @since 2018年12月12日 下午1:44:40
	 * @param request
	 * @return
	 * @throws Exception
	 *             预付完成后的处理
	 */
	@RequestMapping("/prepaySucessToOpen")
	@ResponseBody
	public String prepaySucessToOpen(HttpServletRequest request) throws Exception {
		log.info("预付异步通知。。。。。。");
		String trade_no = request.getParameter("trade_no");
		String trade_status = request.getParameter("trade_status");
		String out_trade_no = request.getParameter("out_trade_no");
		String buyer_id = request.getParameter("buyer_id");
		if (StringUtils.isNotBlank("trade_status") && trade_status.equals("TRADE_SUCCESS")) {
			log.info("验证成功！");
			PayOrderExample example = new PayOrderExample();
			log.info("buyerId:" + buyer_id + " tradeNo:" + trade_no + "outTradeNo:" + out_trade_no);
			example.createCriteria().andIsPayEqualTo((byte) 0).andOpenIdEqualTo(buyer_id)
					.andTransactionIdEqualTo(trade_no).andOutTradeNoEqualTo(out_trade_no);
			List<PayOrder> payOrderList = payOrderMapper.selectByExample(example);
			if (!payOrderList.isEmpty()) {
				PayOrder payOrder = payOrderList.get(0);
				try {
					log.info("调用处理逻辑。。");
					manageCaseBoxService.prepaySucessToOpen(payOrder);
					return "success";
				} catch (Exception e) {
					return "";
				}
			} else {
				log.info("未找到订单。。");
				return "success";
			}

		} else {
			log.info("验证失败。。");
			return "";
		}
	}

	// Prepay
	/**
	 * @author liuCheng
	 * @since 2018年12月12日 下午1:44:40
	 * @param request
	 * @return
	 * @throws Exception
	 *             预付押金完成后的处理
	 */
	@RequestMapping("/prepayPledge")
	@ResponseBody
	public String prepayPledge(HttpServletRequest request) throws Exception {
		String trade_no = request.getParameter("trade_no");
		String trade_status = request.getParameter("trade_status");
		String out_trade_no = request.getParameter("out_trade_no");
		String buyer_id = request.getParameter("buyer_id");
		if (StringUtils.isNotBlank("trade_status") && trade_status.equals("TRADE_SUCCESS")) {
			PayOrderExample example = new PayOrderExample();
			example.createCriteria().andIsPayEqualTo((byte) 0).andOpenIdEqualTo(buyer_id)
					.andTransactionIdEqualTo(trade_no).andOutTradeNoEqualTo(out_trade_no);
			List<PayOrder> payOrderList = payOrderMapper.selectByExample(example);
			if (!payOrderList.isEmpty()) {
				PayOrder payOrder = payOrderList.get(0);
				try {
					manageCaseBoxService.prepaySucessToOpen(payOrder);
					return "success";
				} catch (Exception e) {
					return "";
				}
			} else {
				return "";
			}

		} else {
			return "";
		}
	}

	/**
	 * @author liuCheng
	 * @since 2018年12月12日 下午6:35:28
	 * @param outTradeNo
	 * @return 取消预付款支付后的处理逻辑
	 */
	@RequestMapping("/cancelPrepay")
	@ResponseBody
	public void cancelPrepay(String outTradeNo) {

		// 查询
		PrepayOrderExample selectPrepayOrderExample = new PrepayOrderExample();
		selectPrepayOrderExample.createCriteria().andOutTradeNoEqualTo(outTradeNo);
		List<PrepayOrder> prepayOrderList = prepayOrderMapper.selectByExample(selectPrepayOrderExample);
		if (!prepayOrderList.isEmpty()) {
			PrepayOrder prepayOrder = prepayOrderList.get(0);
			payOrderService.cancelPrepay(prepayOrder);
		}
	}

	/**
	 * @author liuCheng
	 * @since 2019年1月4日 下午4:28:38
	 * @param subject
	 * @param notifyUrl
	 * @param amount
	 * @param out_trade_no
	 * @param openId
	 * @return
	 * @throws Exception
	 *             支付宝支付创建统一订单
	 */
	private AlipayTradeCreateResponse creatAliPay(String subject, String notifyUrl, double amount, String out_trade_no,
			String openId) throws Exception {
		Map<String, Object> map = new HashMap<>();
		map.put("out_trade_no", out_trade_no);
		map.put("total_amount", amount);
		map.put("subject", subject);
		map.put("buyer_id", openId);
		map.put("timeout_express", "2m");
		String jsonString = JSONObject.toJSONString(map);
		AlipayClient alipayClient = new DefaultAlipayClient(AliConfig.URL, AliConfig.APP_ID, AliConfig.PRIVATE_KEY,
				"JSON", "UTF-8", AliConfig.ALIPAY_PUBLIC_KEY, "RSA2");
		AlipayTradeCreateRequest request = new AlipayTradeCreateRequest();
		// 异步通知接口
		request.setNotifyUrl(notifyUrl);
		request.setBizContent(jsonString);
		AlipayTradeCreateResponse response = alipayClient.execute(request);
		return response;
	}

	/**
	 * @author liuCheng
	 * @since 2018年12月12日 下午2:21:11
	 * @param doorNum
	 * @param caseNo
	 * @param manageCaseBox
	 * @param openId
	 * @return 不需要支付直接开门（存物）
	 */
	private Map<String, String> openDoorBySaveAndNoPay(Integer doorNum, String caseNo, ManageCaseBox manageCaseBox,
			String openId, Integer clearHour, Byte payType, Byte payTime, String password) {
		Map<String, String> map = new HashMap<>();
		try {

			manageCaseBoxService.openBoxCommonByXcx(manageCaseBox, openId, AllConst.ACCESS_RECORD_TYPE.SAVE_TYEP,
					AllConst.ACCESS_RECORD_SOURCE.ALI_XCX_SOURCE, AllConst.CASE_BOX_SAVE_SOURCE.ALI_XCX_SAVE_SOURCE,
					clearHour, payType, payTime, password);
			map.put("pagejump", "2");
			map.put("jump", "500");
			map.put("message", "已为您开启" + doorNum + "号门，请存入物品，并关好箱门，谢谢您的合作！！！");
		} catch (Exception e) {
			map.put("pagejump", "1");
			map.put("jump", "200");
			map.put("message", "开启失败，你选择的箱子已被他人抢走了，请重新选择");
		}
		return map;
	}

	/**
	 * 创建预付订单
	 * 
	 * @author liuCheng
	 * @since 2018年12月12日 下午1:22:32
	 * @param nonce_str
	 * @param out_trade_no
	 * @param subject
	 * @param amount
	 * @param openId
	 * @return 统一创建订单（预付订单）
	 * @throws AlipayApiException
	 */
	private Map<String, String> createPrepayOrder(String nonce_str, String out_trade_no, String subject, double amount,
			BigDecimal cashPledge, String openId, ManageCaseBox manageCaseBox, String password) throws Exception {
		log.info("out_trade_no:" + out_trade_no + " subject:" + subject + " amount:" + amount + " cashPledge:"
				+ cashPledge + " openId:" + openId);
		Integer boxId = manageCaseBox.getId();
		Integer doorNum = manageCaseBox.getDoorNum();
		Map<String, Object> map = new HashMap<>();
		map.put("out_trade_no", out_trade_no);
		map.put("total_amount", cashPledge.add(new BigDecimal(amount + "")));
		map.put("subject", subject);
		map.put("buyer_id", openId);
		map.put("timeout_express", "2m");
		log.info("订单支付金额：" + map.get("total_amount"));
		String jsonString = JSONObject.toJSONString(map);
		AlipayClient alipayClient = new DefaultAlipayClient(AliConfig.URL, AliConfig.APP_ID, AliConfig.PRIVATE_KEY,
				"JSON", "UTF-8", AliConfig.ALIPAY_PUBLIC_KEY, "RSA2");
		AlipayTradeCreateRequest request = new AlipayTradeCreateRequest();
		// 异步通知接口
		request.setNotifyUrl(AliConfig.DOMAIN_URL + "/alixcxCommon/prepaySucessToOpen");
		request.setBizContent(jsonString);
		AlipayTradeCreateResponse response = alipayClient.execute(request);
		log.info(response.getBody());
		Map<String, String> returnMap = new HashMap<>();
		if (response.isSuccess()) {
			String tradeNo = response.getTradeNo();
			// 将订单号插入数据库
			try {
				log.info("预付订单插入数据库");
				payOrderService.prepayAliBefore(openId, amount, cashPledge, out_trade_no, tradeNo, boxId, password);
				returnMap.put("jump", "800");
				returnMap.put("doorNum", doorNum.toString());
				returnMap.put("tradeNo", tradeNo);
				returnMap.put("outTradeNo", out_trade_no);

			} catch (Exception e) {
				log.info("预付订单插入数据库失败");
				returnMap.put("jump", "200");
				returnMap.put("openboxMessage", "系统错误，请重试！");
			}
		} else {
			log.info("向支付宝请求预付订单返回失败，未成功false");
			returnMap.put("jump", "200");
			returnMap.put("openboxMessage", "系统错误，请重试！");
		}
		return returnMap;
	}

	/**
	 * @author liuCheng
	 * @since 2018年12月12日 下午1:22:32
	 * @param nonce_str
	 * @param out_trade_no
	 * @param subject
	 * @param
	 * @param openId
	 * @return 统一创建订单（押金订单）
	 * @throws AlipayApiException
	 */
	private Map<String, String> createPledgeOrder(String nonce_str, String out_trade_no, String subject,
			BigDecimal cashPledge, String openId, ManageCaseBox manageCaseBox, String password) throws Exception {
		Integer boxId = manageCaseBox.getId();
		Integer doorNum = manageCaseBox.getDoorNum();
		Map<String, Object> map = new HashMap<>();
		map.put("out_trade_no", out_trade_no);
		map.put("total_amount", cashPledge.toString());
		map.put("subject", subject);
		map.put("buyer_id", openId);
		map.put("timeout_express", "2m");
		String jsonString = JSONObject.toJSONString(map);
		AlipayClient alipayClient = new DefaultAlipayClient(AliConfig.URL, AliConfig.APP_ID, AliConfig.PRIVATE_KEY,
				"JSON", "UTF-8", AliConfig.ALIPAY_PUBLIC_KEY, "RSA2");
		AlipayTradeCreateRequest request = new AlipayTradeCreateRequest();
		// 异步通知接口
		request.setNotifyUrl(AliConfig.DOMAIN_URL + "/alixcxCommon/prepayPledge");
		request.setBizContent(jsonString);
		AlipayTradeCreateResponse response = alipayClient.execute(request);

		Map<String, String> returnMap = new HashMap<>();
		if (response.isSuccess()) {
			String tradeNo = response.getTradeNo();
			// 将订单号插入数据库
			try {
				log.info("订单插入数据库");
				payOrderService.prepayAliBefore(openId, 0.0, cashPledge, out_trade_no, tradeNo, boxId, password);
				returnMap.put("jump", "800");
				returnMap.put("doorNum", doorNum.toString());
				returnMap.put("tradeNo", tradeNo);
				returnMap.put("outTradeNo", out_trade_no);

			} catch (Exception e) {
				log.info("订单插入数据库失败");
				returnMap.put("jump", "200");
				returnMap.put("openboxMessage", "系统错误，请重试！");
			}
		} else {
			log.info("向支付宝发送订单失败");
			returnMap.put("jump", "200");
			returnMap.put("openboxMessage", "系统错误，请重试！");
		}
		return returnMap;
	}

	/**
	 * @author liuCheng
	 * @since 2018年12月12日 下午5:23:59
	 * @param manageCaseBox 箱子信息
	 * @param openId 用户唯一标识
	 * @param doorNum 几号门
	 * @return 不用付费的取物
	 */
	private Map<String, Object> openMyCommonBoxByXcxAndNoPay(ManageCaseBox manageCaseBox, String openId,
			Integer doorNum) {
		Map<String, Object> returnMap = new HashMap<>();
		try {
			manageCaseBoxService.openMyCommonBoxByXcx(manageCaseBox, openId, AllConst.ACCESS_RECORD_TYPE.GET_TYPE,
					AllConst.ACCESS_RECORD_SOURCE.ALI_XCX_SOURCE);
			returnMap.put("code", "200");
			returnMap.put("openboxMessage", "已为您开启箱" + doorNum + "号箱门，请取走您的全部物品，并关好箱门！");
			return returnMap;

		} catch (Exception e) {
			returnMap.put("code", "500");
			returnMap.put("openboxMessage", "开启失败，请重试");
			return returnMap;
		}
	}
	
	/**
	 * @author liuCheng
	 * @since 2018年12月12日 下午5:23:59
	 * @param manageCaseBox
	 * @param openId
	 * @param cost  费用
	 * @return  需要支付,从押金扣除
	 */
	private Map<String, Object> openMyCommonBoxByXcxAndNeedPay(ManageCaseBox manageCaseBox, String openId,Integer doorNum,BigDecimal cost) {
		Map<String, Object> returnMap = new HashMap<>();
		try {
			manageCaseBoxService.openMyCommonBoxByXcx(manageCaseBox, openId, AllConst.ACCESS_RECORD_TYPE.GET_TYPE,
					AllConst.ACCESS_RECORD_SOURCE.ALI_XCX_SOURCE,cost);
			returnMap.put("code", "200");
			returnMap.put("openboxMessage", "已为您开启箱" + doorNum + "号箱门，请取走您的全部物品，并关好箱门！");
			return returnMap;
		} catch (Exception e) {
			returnMap.put("code", "500");
			returnMap.put("openboxMessage", "开启失败，请重试");
			return returnMap;
		}
	}






	/**
	 * @author liuCheng
	 * @since 2018年12月21日 下午4:35:17
	 * @param manageCaseBox
	 * @param openId
	 * @param doorNum
	 * @return 中途取物---不用付费
	 */
	private Map<String, Object> openMyCommonBoxByXcxAndNoPayMidWay(ManageCaseBox manageCaseBox, String openId,
			Integer doorNum) {
		Map<String, Object> returnMap = new HashMap<>();
		try {
			manageCaseBoxService.openMidWayMyCommonBoxByXcx(manageCaseBox, openId,
					AllConst.ACCESS_RECORD_TYPE.MIDWAY_GET_TYPE, AllConst.ACCESS_RECORD_SOURCE.ALI_XCX_SOURCE);
			returnMap.put("code", "101");
			returnMap.put("openboxMessage", "已为您开启箱" + doorNum + "号箱门，请取走您的全部物品，并关好箱门！");
			return returnMap;

		} catch (Exception e) {
			returnMap.put("code", "101");
			returnMap.put("openboxMessage", "开启失败，请重试");
			return returnMap;
		}
	}

}
